package org.jeecg.modules.engineering.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CacheConstant;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;
import org.jeecg.common.util.RedisUtil;
import org.jeecg.common.util.StringUtils;
import org.jeecg.modules.engineering.entity.EquipDataCollectorType;
import org.jeecg.modules.engineering.entity.EquipInfo;
import org.jeecg.modules.engineering.mapper.EquipDataCollectorTypeMapper;
import org.jeecg.modules.engineering.mapper.EquipInfoMapper;
import org.jeecg.modules.engineering.service.IEquipLinkThingService;
import org.jeecg.modules.engineering.util.HMACSHAHelper;
import org.jeecg.modules.engineering.vo.LinkThingDeviceKey;
import org.jeecg.modules.system.util.RestTemplateUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Service
@Slf4j
public class EquipLinkThingServiceImpl implements IEquipLinkThingService {

    @Autowired
    private RestTemplateUtil restTemplateUtil;

    @Autowired
    private EquipInfoMapper equipInfoMapper;

    @Autowired
    private RedisUtil redisUtil;

    @Autowired
    private EquipDataCollectorTypeMapper equipDataCollectorTypeMapper;

    private String getToken(){
        String token = (String) redisUtil.get(CommonConstant.LING_THING_TOKEN);
        if(token != null){
            log.info("从redis获取的物管中心token信息为:"+token);
            return token;
        }
        synchronized (this){
            token = (String) redisUtil.get(CommonConstant.LING_THING_TOKEN);
            if(token != null){
                log.info("同步块从redis获取的物管中心token信息为:"+token);
                return token;
            }
            //token为空，调用接口获取token
            Map<String, Object> map= Maps.newHashMap();
            map.put("Txn_Type","K001");
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("Api_Key",CommonConstant.LING_THING_APP_KEY);
            jsonObject.put("Signal", HMACSHAHelper.getSHA1Signature(CommonConstant.LING_THING_APP_KEY.getBytes(),CommonConstant.LING_THING_SECRET_KEY.getBytes()));
            map.put("Data",jsonObject);
            JSONObject resultJson = restTemplateUtil.postForEntity(map,CommonConstant.LING_THING_BASEURL,null);
            Integer code = resultJson.getInteger("Status");
            if(code != null && code.equals(0)){
                JSONObject resJson = resultJson.getJSONObject("Data");
                token = resJson.getString("Token");
                if(StringUtils.isNotEmpty(token)){
                    redisUtil.set(CommonConstant.LING_THING_TOKEN, token,60 * 50);
                }
            }else{
                String msg = jsonObject.getString("Errmsg");
                log.error(String.format("获取的结果异常，异常码：%s,错误信息：%s",code,msg));
            }
        }
        log.info("最终获取的token为:"+token);
        if(StringUtils.isEmpty(token)){
            log.error("获取物管中心token信息为空");
            throw new JeecgBootException("获取物管中心token信息为空");
        }
        return token;
    }

    @Override
    public void addEquip(){
        List<EquipInfo> infos = equipInfoMapper.selectByNoSignKey();
        if(infos == null || infos.size() == 0){
            return;
        }
        List<String> uids = new ArrayList<>();
        for (EquipInfo info : infos){
            uids.add(info.getEquipCode());
        }
        Map<String,String> maps = addEquipToLinkThing(listToArray(uids));
        if(maps == null || maps.size() == 0){
            return;
        }
        int count = equipInfoMapper.updateSignKeyByCode(maps);
        if(count > 0){
            for (EquipInfo info : infos){
                String signKey = maps.get(info.getEquipCode());
                if(signKey != null){
                    info.setSignKey(signKey);
                    setToRedis(info);
                }
            }
        }
        try{
            //同步设备信息到物管中心
            syncEquipInfo(infos);
        }catch (Exception e){
            e.printStackTrace();
            log.error("数据同步到物管中心出现异常"+e);
        }
    }

    private void setToRedis(EquipInfo entity){
        if(entity == null){
            return;
        }
        redisUtil.set(CacheConstant.REDIS_TABLES+"equip_info:id:"+entity.getId(), JSONObject.toJSONString(entity));
        redisUtil.set(CacheConstant.REDIS_TABLES+"equip_info:otherKey:"+entity.getEquipOutCode(),entity.getId());
    }
    @Override
    public Map<String,String> addEquip(String uid){
        return addEquip(Collections.singletonList(uid));
    }

    @Override
    public Map<String,String> addEquip(List<String> uids){
        return addEquipToLinkThing(listToArray(uids));
    }

    private JSONArray listToArray(List<String> uids){
        if(uids == null || uids.size() == 0){
            return null;
        }
        JSONArray array = new JSONArray();
        for(String uid :uids){
            JSONObject json = new JSONObject();
            json.put("Uid",uid);
            array.add(json);
        }
        return array;
    }
    private Map<String,String> addEquipToLinkThing(JSONArray uids){
        Map<String, Object> map= Maps.newHashMap();
        map.put("Txn_Type","D001");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Api_Key",CommonConstant.LING_THING_APP_KEY);
        jsonObject.put("Token",getToken());
        jsonObject.put("Uid_List", uids);
        map.put("Data",jsonObject);
        try{
            JSONObject resultJson = restTemplateUtil.postForEntity(map,CommonConstant.LING_THING_BASEURL,null);
            if(resultJson != null  && "0".equals(resultJson.getString("Status"))){
                JSONObject data = resultJson.getJSONObject("Data");
                JSONArray array = data.getJSONArray("Device_KeyList");
                List<LinkThingDeviceKey> deviceKeys = JSONArray.parseArray(array.toJSONString(),LinkThingDeviceKey.class);
                if(deviceKeys == null || deviceKeys.size() == 0 ){
                    return  null;
                }
                return deviceKeys.stream().collect(Collectors.toMap(LinkThingDeviceKey::getUid,LinkThingDeviceKey::getDevice_SignKey));
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("添加设备到物管中心出现异常"+e);
        }
        return null;
    }

    @Override
    public void syncEquipInfo(List<EquipInfo> infos){
        Map<String, Object> map= Maps.newHashMap();
        map.put("Txn_Type","D002");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Token",getToken());
        jsonObject.put("Device_InfoList", toLinkThingInfoData(infos));
        jsonObject.put("Api_Key",CommonConstant.LING_THING_APP_KEY);
        map.put("Data",jsonObject);
        try{
            JSONObject resultJson = restTemplateUtil.postForEntity(map,CommonConstant.LING_THING_BASEURL,null);
            if(resultJson != null  && "0".equals(resultJson.getString("Status"))){
                JSONObject data = resultJson.getJSONObject("Data");
                String success_list = data.getString("Success_List");
                log.info("同步成功的列表为："+success_list);
                String failed_list = data.getString("Failed_List");
                log.info("同步失败的列表为："+failed_list);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("同步设备信息到物管中心出现异常"+e);
        }
    }

    private JSONArray toLinkThingInfoData(List<EquipInfo> infos){
        if(infos == null || infos.size() == 0){
            return null;
        }
        Map<String,EquipDataCollectorType> types = null;
        JSONArray array = new JSONArray();
        if(infos.size() > CommonConstant.LING_THING_QUERY_ALL_SIZE){
            types = new HashMap<>();
            List<EquipDataCollectorType> typeList = equipDataCollectorTypeMapper.selectListAll();
            if(typeList != null && typeList.size() > 0){
                for (EquipDataCollectorType type : typeList){
                    types.put(type.getSortId()+"-"+type.getCollectorCode(),type);
                }
            }
        }
        for (EquipInfo info : infos){
            if(StringUtils.isBlank(info.getSignKey())){
                continue;
            }
            JSONObject json = new JSONObject(new TreeMap<>());
            json.put("Addr",info.getEquipPosition());//安装地址
            json.put("Alias",info.getEquipName());//终端别名
            json.put("Cpname",info.getEquipManufacturer() == null ? "": info.getEquipManufacturer());//所属企业名称
            EquipDataCollectorType type;
            if(types != null){
                type = types.get(info.getSortId()+"-"+CommonConstant.LING_THING_CODE);
            }else{
                type = equipDataCollectorTypeMapper.getTypeByCollector(info.getSortId(),CommonConstant.LING_THING_CODE);
            }
            json.put("DeviceType",type == null?CommonConstant.LING_THING_DEFAULT_TYPE:type.getCollectorType());//设备类型
            json.put("Longitude",info.getEquipLongitude() == null ? "": info.getEquipLongitude() +"");//经度
            json.put("Latitude",info.getEquipDimension() == null ? "": info.getEquipDimension() +"");//维度
            json.put("Uid",info.getEquipCode());//设备编号
            json.put("WorkFlag",info.getEquipStatus() == 0 ? 0 : 1);
            String sign = HMACSHAHelper.getSHA1Signature(json.toJSONString().getBytes(),info.getSignKey().getBytes());
            json.put("Signature",sign);//签名，需要以signKey进行签名，暂时待定
            array.add(json);
        }
        return array;
    }


    public static void main(String[] args) {
        JSONObject json = new JSONObject(new TreeMap<>());
        json.put("Addr","小区东门出入口");//安装地址
        json.put("Alias","摄像头2");//终端别名
        json.put("Cpname","富强");//所属企业名称
        json.put("DeviceType","00000");//设备类型
        json.put("Latitude","31.251111");//维度
        json.put("Longitude","121.391442");//经度
        json.put("Uid","GXSB113");//设备编号
        json.put("WorkFlag",0);
        //173826158b5bc8f9c21ebca744977d68fc881e0d
        //0E697254418F4F538E7152239DC295A0
        System.out.println(json.toJSONString());
        String sign = HMACSHAHelper.getSHA1Signature(JSONObject.toJSON(json).toString().getBytes(),"1CAF2232EAB9411AA267D29947BBC2C1".getBytes());
        json.put("Signature",sign);//签名，需要以signKey进行签名，暂时待定
        System.out.println(sign);
    }

    @Override
    public void postEquipStatus(JSONArray status){
        Map<String, Object> map= Maps.newHashMap();
        map.put("Txn_Type","D003");
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("Token",getToken());
        jsonObject.put("Api_Key",CommonConstant.LING_THING_APP_KEY);
        jsonObject.put("Device_StatusList", status);
        map.put("Data",jsonObject);
        try{
            JSONObject resultJson = restTemplateUtil.postForEntity(map,CommonConstant.LING_THING_BASEURL,null);
            if(resultJson != null  && "0".equals(resultJson.getString("Status"))){
                log.info("同步到物管中心成功：");
                JSONObject data = resultJson.getJSONObject("Data");
                String success_list = data.getString("Success_List");
                log.info("同步成功的列表为："+success_list);
                String failed_list = data.getString("Failed_List");
                log.info("同步失败的列表为："+failed_list);
            }
        }catch (Exception e){
            e.printStackTrace();
            log.error("上传设备数据到物管中心出现异常"+e);
        }
    }
}
